/*
 * designassignment4.c
 *
 * Created: 3/22/2014 5:05:46 PM
 *  Author: Yosemit Xolalpa Rosales
 */ 

 
#define F_CPU 1000000     // XTAL = 1MHz 
#include <avr/io.h>
#include <util/delay.h>

void SetValues(uint8_t, uint8_t, int, int, int);
int Dcycle = 255;
int period = 0x1;

int main(void)
{
        DDRB = 0x08;                //  Enable OC2A  (PB3 -> 2^3 = 8)
        PORTB = 0x00;			    //  Set Output high - turn all LEDs off
        DDRD = 0x60;                //  Enable OC0A / OC0B  (PD6/PD5 -> 2^6 + 2^5 = 96 = 0x60)
        PORTD = 0x00;               //  Set Output high - turn all LEDs off
        
		//      Initialize Timer0/2
		//  (1 << WGMx0, WGMx1) = Fast PWM,  (1 << COMnX1, COMnX0) = Set Output(OCRnX) registers on compare match
        TCCR0A ^= ( 1 << COM0A1 ) ^ ( 1 << COM0A0 ) ^ ( 1 << COM0B1 ) ^ ( 1 << COM0B0 ) ^ ( 1 << WGM01 ) ^ ( 1 << WGM00 );    //Phase-Correct PWM Mode  
        TCCR2A ^= ( 1 << COM2A1 ) ^ ( 1 << COM2A0 ) ^ ( 1 << WGM21 ) ^ ( 1 << WGM20 );
        

        while(1)
        {						
				
				while(Dcycle > 0) //Hue BLUE Hue Hue Hue
				{
					SetValues(!period, period, !Dcycle, 200, Dcycle); //Prescaler Timer0: ~period, Prescaler period: 1024, Duty Cycles: (100% - 0%), 78%, (0% - 100%)
					_delay_ms(10);		//delay for 10 millisecs
					Dcycle--;			//dec Dcycle
					period++;			//inc period
					if(period >= 0x5)	//make sure we don't modify WGMx2 bit
					{
						period = 0x1;	//reset period to 0x1
					}
				}
				
				//**** restore
				Dcycle = 255;
				period = 0x1;
				_delay_ms(10);
					
				while( Dcycle > 0)		//GREEN
				{
					SetValues(0x1, 0x01, 255, Dcycle, 255); //Prescaler Timer0: ~period, Prescaler period: 1024, Duty Cycles: 0%, (0% - 100%), 0%
					_delay_ms(10);		//delay for 10millisecs
					Dcycle--;			//dec Dcycle
				}
				
				//**** restore
				Dcycle = 255;
				_delay_ms(10);
				
				while( Dcycle > 0)		//RED
				{
					SetValues(0x1, 0x01, Dcycle, 255, 255); //RED hue hue hue
					_delay_ms(10);
					Dcycle--;
				}
				
				//**** restore
				Dcycle = 255;
				_delay_ms(10);
				
		}
}

//----------------------------------------------------------------------------------------------------
//      1.	Function to adjust period of PWM signals by changing the Prescaler for Timers 0/2;
//			changes the color of the RGB LED.
//      2.	Adjusts the duty cycles for pwm 1,2,3; changes the brightness of the RGB LED.

void SetValues(uint8_t PRE0, uint8_t PRE2, int PWM1, int PWM2, int PWM3)
{
        TCCR0B = PRE0;				// TCCR0B |=  (CS2:CS0)
        TCCR2B = PRE2;				// TCCR2B |=  (CS2:CS0)
		OCR0A = PWM1; //red			// OCRx = duty cycle(decimal) * 256
		OCR0B = PWM2; //green
		OCR2A = PWM3; //blue
}